﻿using Daemon.Common;
using Daemon.Data.Infrastructure.Auth;
using Daemon.Middleware;
using Daemon.Model;
using Daemon.Service.Contract;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Web.Http.Controllers;

namespace Daemon.Common.Auth
{
	public class RoleAuthorizationHandler : AuthorizationHandler<PermissionRequirement>
	{
		private readonly ILogger<RoleAuthorizationHandler> _logger;

		private readonly IHttpContextAccessor _httpContextAccessor;

		public IAuthenticationSchemeProvider _schemes { get; set; }

		public RoleAuthorizationHandler(ILogger<RoleAuthorizationHandler> logger, IHttpContextAccessor httpContextAccessor, IAuthenticationSchemeProvider schemes)
		{
			_logger = logger;
			this._httpContextAccessor = httpContextAccessor;
			_schemes = schemes;
		}

		protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
		{
			var httpContext = _httpContextAccessor.HttpContext;
			var handlers = httpContext.RequestServices.GetRequiredService<IAuthenticationHandlerProvider>();
			foreach (var scheme in await _schemes.GetRequestHandlerSchemesAsync())
			{
				var handler = await handlers.GetHandlerAsync(httpContext, scheme.Name) as IAuthenticationRequestHandler;
				if (handler != null && await handler.HandleRequestAsync())
				{
					context.Fail();
					return;
				}
			}

			var defaultAuthenticate = await _schemes.GetDefaultAuthenticateSchemeAsync();
			if (defaultAuthenticate != null)
			{
				var result = await httpContext.AuthenticateAsync(defaultAuthenticate.Name);
				if (result?.Principal != null)
				{
					httpContext.User = result.Principal;
					context.Succeed(requirement);
					return;
				}
			}

			context.Succeed(requirement);
		}


		/// <summary>
		/// 
		/// </summary>
		/// <param name="roleName"></param>
		/// <returns></returns>
		private List<string> AuthorizationMenuPath(string roleName)
		{
			switch (roleName)
			{
				case "Admin":
					return new List<string>() { "/Login/Index" };
				default:
					return new List<string>() { "/Login/Index" };
			}

		}
	}
}
